package com.example.screenprojection.Socket;

import android.graphics.Bitmap;

import com.example.screenprojection.Utils.MyUtils;

import java.io.DataInputStream;
import java.io.InputStream;
import java.net.Socket;

public class BitmapClientRunnable implements Runnable {

    private static final String TAG = "SocketClientRunnable";

    private Socket socket;
    private String ip;
    private int port;


    public void setIp(String ip) {
        this.ip = ip;
    }

    public void setPort(int port) {
        this.port = port;
    }

    @Override
    public void run() {
        ClientRun();
    }

    public void close() {
        ClientClose();
    }

    private boolean ClientConnect() {
        try {
            socket = new Socket(ip,port);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        if (listener != null) {
            listener.onClientConnect();
        }
        return true;
    }

    private boolean ClientIsConnect() {
        return socket != null && !socket.isClosed() && socket.isConnected();
    }

    private void ClientClose() {
        try {
            if (socket != null) {
                socket.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (listener != null) {
            listener.onClientClose();
        }
    }

    private void ClientSleep(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private final static byte[] PACKAGE_HEAD = {(byte)0xFF, (byte)0xCF, (byte)0xFA, (byte)0xBF, (byte)0xF6, (byte)0xAF, (byte)0xFE, (byte)0xFF};

    private void ClientReceiveBitmap() {
        try {
            InputStream inputStream = socket.getInputStream();
            boolean isHead = true;
            for (byte b : PACKAGE_HEAD) {
                byte head = (byte) inputStream.read();
                if (head != b) {
                    isHead = false;
                    break;
                }
            }
            if (isHead) {
                DataInputStream dataInputStream = new DataInputStream(inputStream);
                int width = dataInputStream.readInt();
                int height = dataInputStream.readInt();
                int len = dataInputStream.readInt();
                byte[] data = new byte[len];
                dataInputStream.readFully(data, 0, len);
                Bitmap bitmap = MyUtils.BytestoBitmap(data);
                if (bitmap != null) {
                    if (listener != null) {
                        listener.onClientReceiveBitmap(bitmap, width, height);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void ClientRun() {
        if (!ClientConnect()) {
            return;
        }
        while (true) {
            while (ClientIsConnect()) {
                ClientReceiveBitmap();
                ClientSleep(10);
            }
        }
    }

    private ClientListener listener;

    public interface ClientListener {
        void onClientConnect();
        void onClientClose();
        void onClientReceiveBitmap(Bitmap bitmap, int width, int height);
    }

    public void setListener(ClientListener listener) {
        this.listener = listener;
    }
}
